package icerts

import (
	"context"

	"gitee.com/djaf/my-certs/app/classes/accounts"
	"gitee.com/djaf/my-certs/app/classes/certificates"
	"gitee.com/djaf/my-certs/app/classes/domains"
	"gitee.com/djaf/my-certs/app/classes/keypairs"
	"gitee.com/djaf/my-certs/app/web/dto"
)

// CSRServiceImpl ...
type CSRServiceImpl struct {

	//starter:component

	_as func(certificates.CSRService) //starter:as("#")

	CSRDao certificates.CSRDAO //starter:inject("#")

	ServiceCerts    certificates.Service    //starter:inject("#")
	ServiceCSR      certificates.CSRService //starter:inject("#")
	ServiceAccounts accounts.Service        //starter:inject("#")
	ServiceDomains  domains.Service         //starter:inject("#")
	ServiceKeyPairs keypairs.Service        //starter:inject("#")
}

func (inst *CSRServiceImpl) _impl() certificates.CSRService {
	return inst
}

// NewRequest ...
func (inst *CSRServiceImpl) NewRequest(ctx context.Context, req *dto.CSR) error {
	item, err := inst.CSRDao.Insert(nil, req)
	if err != nil {
		return err
	}
	*req = *item
	runner := &csrRunner{
		context: ctx,
		csr:     item,

		serviceCerts:    inst.ServiceCerts,
		serviceCSR:      inst.ServiceCSR,
		serviceKeyPairs: inst.ServiceKeyPairs,
		serviceDomains:  inst.ServiceDomains,
		serviceAccounts: inst.ServiceAccounts,
	}
	go func() {
		runner.run()
	}()
	return nil
}

// // Verify ...
// func (inst *CSRServiceImpl) Verify(ctx context.Context, req *dto.CSR) error {
// 	id := req.ID
// 	item2, err := inst.CSRDao.Update(nil, id, func(item *dto.CSR) {
// 		item.VerifyDone = true
// 	})
// 	if err != nil {
// 		return err
// 	}
// 	*req = *item2
// 	return nil
// }

// UpdateState ...
func (inst *CSRServiceImpl) UpdateState(ctx context.Context, req *dto.CSR) error {
	id := req.ID
	_, err := inst.CSRDao.Update(nil, id, func(target *dto.CSR) {
		if req.Challenge != nil {
			target.Challenge = req.Challenge
		}
		target.Cancelled = req.Cancelled
	})
	return err
}

// GetState ...
func (inst *CSRServiceImpl) GetState(ctx context.Context, req *dto.CSR) error {
	id := req.ID
	item2, err := inst.CSRDao.Find(nil, id)
	if err != nil {
		return err
	}
	*req = *item2
	return nil
}

// Cancel ...
func (inst *CSRServiceImpl) Cancel(ctx context.Context, req *dto.CSR) error {
	id := req.ID
	item2, err := inst.CSRDao.Update(nil, id, func(item *dto.CSR) {
		item.Cancelled = true
	})
	if err != nil {
		return err
	}
	*req = *item2
	return nil
}

////////////////////////////////////////////////////////////////////////////////
